package com.demo.core.utils;

import cn.hutool.core.thread.ExecutorBuilder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.*;

/**
 * @author Tan-Bowen
 * @description TODO 线程池
 * @date 2021/7/27 16:27
 */
@Component
@Slf4j
@Getter
public class ThreadPool implements DisposableBean {

    private ExecutorService executor;

    /**
     * 核心线程数
     */
    @Value("${thread.pool.corePoolSize:32}")
    private int corePoolSize;

    /**
     * 最大线程数
     */
    @Value("${thread.pool.maxPoolSize:128}")
    private int maxPoolSize;

    /**
     * 线程存货时间
     */
    @Value("${thread.pool.keepAliveTime:30}")
    private long keepAliveTime;

    @PostConstruct
    void init() {
            ExecutorBuilder builder = ExecutorBuilder.create()
                    .setCorePoolSize(corePoolSize)
                    .setMaxPoolSize(maxPoolSize)
                    .setKeepAliveTime(keepAliveTime, TimeUnit.SECONDS)
                    .setWorkQueue(new LinkedBlockingQueue());
            executor = builder.build();
            log.info("创建线程池成功：corePoolSize={},maxPoolSize={},keepAliveTime={}s", corePoolSize, maxPoolSize, keepAliveTime);
    }

    /**
     * @param [runnable]
     * @return void
     * @author Tan-Bowen
     * @description TODO 执行线程
     * @date 2021/7/27 16:28
     * @paramType [java.lang.Runnable]
     */
    public void execute(Runnable runnable) {
        executor.execute(runnable);
    }

    /**
     * @param [t]
     * @return java.util.concurrent.Future<T>
     * @author Tan-Bowen
     * @description TODO 执行线程获得一个回调结果
     * @date 2021/7/27 16:28
     * @paramType [java.util.concurrent.Callable<T>]
     */
    public <T> Future<T> submit(Callable<T> t) {
        return executor.submit(t);
    }

    public void shutdown(boolean isNow) {
        if (null != executor) {
            if (isNow) {
                log.info("暴力关闭线程池。。。");
                executor.shutdownNow();
            } else {
                log.info("优雅的关闭线程池。。。");
                executor.shutdown();
            }
        }
    }


    @Override
    public void destroy() throws Exception {
        shutdown(false);
    }
}
